package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strings"
)

func runCmd(cmd *exec.Cmd) error {

	buf := new(bytes.Buffer)
	buf.WriteByte('\n')

	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	cmd.Env = environ(cmd.Env)
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("%s failed: %v%s", strings.Join(cmd.Args, " "), err, buf)
	}

	return nil
}

func goBuild(src string, env []string, args ...string) error {
	return goCmd("build", []string{src}, env, args...)
}

func goBuildAt(at string, src string, env []string, args ...string) error {
	return goCmdAt(at, "build", []string{src}, env, args...)
}

func goInstall(srcs []string, env []string, args ...string) error {
	return goCmd("install", srcs, env, args...)
}

func goCmd(subcmd string, srcs []string, env []string, args ...string) error {
	return goCmdAt("", subcmd, srcs, env, args...)
}

func goCmdAt(at string, subcmd string, srcs []string, env []string, args ...string) error {
	cmd := exec.Command("go", subcmd)

	/*
		tags := buildTags
		if len(tags) > 0 {
			cmd.Args = append(cmd.Args, "-tags", strings.Join(tags, " "))
		}
		if buildV {
			cmd.Args = append(cmd.Args, "-v")
		}
		if subcmd != "install" && buildI {
			cmd.Args = append(cmd.Args, "-i")
		}
		if buildX {
			cmd.Args = append(cmd.Args, "-x")
		}
		if buildGcflags != "" {
			cmd.Args = append(cmd.Args, "-gcflags", buildGcflags)
		}
		if buildLdflags != "" {
			cmd.Args = append(cmd.Args, "-ldflags", buildLdflags)
		}
		if buildTrimpath {
			cmd.Args = append(cmd.Args, "-trimpath")
		}
		if buildWork {
			cmd.Args = append(cmd.Args, "-work")
		}
	*/

	cmd.Args = append(cmd.Args, args...)
	cmd.Args = append(cmd.Args, srcs...)
	cmd.Env = append([]string{}, env...)
	cmd.Dir = at
	return runCmd(cmd)
}

func goEnv(name string) string {
	val, err := exec.Command("go", "env", name).Output()
	if err == nil {
		return strings.TrimSpace(string(val))
	}

	if val := os.Getenv(name); val != "" {
		return val
	}

	return ""
}

func tryClean(args []string) error {

	buf := new(bytes.Buffer)
	buf.WriteString(`<?xml version="1.0" encoding="utf-8"?>`)
	err := manifestTmpl.Execute(buf, manifestTmplData{
		// TODO(crawshaw): a better package path.
		JavaPkgPath: "org.golang.todo." + "basic",
		Name:        strings.Title("basic"),
		LibName:     "basic.so",
	})

	if err != nil {
		return err
	}

	manifestData := buf.Bytes()
	fmt.Fprintf(os.Stderr, "generated AndroidManifest.xml:\n%s\n", manifestData)

	/**/
	ins := bytes.NewBuffer(manifestData)
	kk, err := binaryXML(ins)
	if err != nil {
		return err
	}

	fp, _ := os.Create("temp.bin")
	fp.Write(kk)
	fp.Close()
	return nil
}

func printUsage(w io.Writer) {
	fmt.Fprintf(w, "Usage:\n")
	fmt.Fprintf(w, "\t%s command [args]\n", os.Args[0])
	fmt.Fprintf(w, "\n")
	fmt.Fprintf(w, "Commands:\n")
	fmt.Fprintf(w, "\tbuild:\n")
	fmt.Fprintf(w, "\tclean:\n")
	fmt.Fprintf(w, "\tpack:\n")
	fmt.Fprintf(w, "\thelp:\n")
	fmt.Fprintf(w, "\n")
	return
}

func printHelp(w io.Writer, args []string) {
	fmt.Fprintf(w, "")
}

func main() {
	var ercode int
	var err error

	/**/
	fmt.Printf("args, %d\n", len(os.Args))
	ercode = 0

	/**/
	if len(os.Args) < 2 {
		printUsage(os.Stderr)
		os.Exit(2)
	}

	switch os.Args[1] {
	case "build":
		ercode = tryBuild(os.Args[2:])

	case "clean":
		err = tryClean(os.Args[2:])
		if err != nil {
			fmt.Println("clean, ", err)
		}

	case "pack":
		err = tryPack(os.Args[2:])
		if err != nil {
			fmt.Println("pack, ", err)
		}

	case "help":
		if len(os.Args) < 2 {
			printUsage(os.Stderr)
			os.Exit(2)
		} else {
			printHelp(os.Stderr, os.Args[2:])
			os.Exit(0)
		}

	default:
		printUsage(os.Stderr)
		os.Exit(2)
	}

	os.Exit(ercode)
	return
}
